package bma.common.langutil.ai.common;

import bma.common.langutil.ai.stack.AIStack;
import bma.common.langutil.ai.vm.AIContext;
import bma.common.langutil.ai.vm.AIContextThread;

/**
 * AI运行状态，可以利用该对象重新执行相关的代码<br/>
 * 包含: AIExecutor,AIFunction,AIStack
 * 
 * @author guanzhong
 * 
 */
public class AIRuntime<TYPE> {

	private final AIContext context;
	private final AIFunction<TYPE> function;
	private final AIStack<TYPE> stack;

	public AIRuntime(AIFunction<TYPE> function, AIStack<TYPE> stack) {
		super();
		this.context = AIContextThread.create();
		this.function = function;
		this.stack = stack;
	}

	public static <TYPE> AIRuntime<TYPE> create(AIFunction<TYPE> function,
			AIStack<TYPE> stack) {
		return new AIRuntime<TYPE>(function, stack);
	}

	public AIContext getContext() {
		return context;
	}

	public AIFunction<TYPE> getFunction() {
		return function;
	}

	public AIStack<TYPE> getStack() {
		return stack;
	}

	/**
	 * 在原有AI进程执行
	 * 
	 * @param newStack
	 * @return
	 */
	public boolean run(final AIStack<TYPE> newStack) {
		Runnable r = new Runnable() {
			@Override
			public void run() {
				function.apply(newStack != null ? newStack : stack);
			}
		};

		if (this.context == null) {
			r.run();
			return true;
		} else {
			this.context.execute(r);
			return false;
		}
	}

	/**
	 * 直接在当前AI进程执行
	 * 
	 * @param newStack
	 * @return
	 */
	public boolean apply(final AIStack<TYPE> newStack) {
		return function.apply(newStack != null ? newStack : stack);
	}

}
